home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1994 June: Reference Library / Dev.CD Jun 94.toast / Periodicals / develop / develop Issue 15 / develop 15 code / QD GX Shell / Exceptions.h next >
Encoding:
C/C++ Source or Header  |  1993-06-02  |  23.9 KB  |  838 lines  |  [TEXT/MPS ]

  1.  
  2. /*********************************************************************
  3.  
  4. FILENAME
  5.     Exceptions.h
  6.     
  7. DESCRIPTION
  8.     A collection of routines and macros to handle assertions and
  9.     exceptions.
  10.  
  11. COPYRIGHT
  12.     Copyright © Apple Computer, Inc. 1989-1991
  13.  
  14. ROUTINES
  15.     EXTERNALS
  16.         dprintf
  17.         check_dprintf
  18.         checkpos_dprintf
  19.  
  20. MACROS
  21.     EXTERNALS
  22.         check
  23.         ncheck
  24.         check_action
  25.         ncheck_action
  26.         require
  27.         nrequire
  28.         require_action
  29.         nrequire_action
  30.         resume
  31.  
  32.         
  33. NOTE
  34.     To keep code size down, use these routines and macros with the C
  35.     compiler option -b2 or -b3. This will eliminate duplicate strings
  36.     within a procedure.
  37.  
  38. *********************************************************************/
  39.  
  40. #ifndef __EXCEPTIONS__
  41. #define __EXCEPTIONS__
  42.  
  43. /*********************************************************************
  44.  
  45. INCLUDES
  46.  
  47. *********************************************************************/
  48.  
  49. #ifndef    __TYPES__
  50. #include    <Types.h>
  51. #endif
  52.  
  53. /*<FF>*/
  54. /*********************************************************************
  55.  
  56. CONSTANTS AND CONTROL
  57.  
  58. *********************************************************************/
  59.  
  60. /*
  61.     These defines are used to control the amount of information
  62.     displayed when an assertion fails. DEBUGOFF and WARN will run
  63.     silently. MIN will simply break into the debugger. ON will break
  64.     and display the assertion that failed and the exception (for
  65.     require statements). FULL will also display the source file name
  66.     and line number. SYM does a SysBreak and is usefull when using a
  67.     symbolic debugger like SourceBug or SADE. They should be set into
  68.     DEBUGLEVEL. The default LEVEL is OFF.
  69. */
  70.  
  71. #define DEBUGOFF        0
  72. #define DEBUGWARN        1
  73. #define DEBUGMIN        2
  74. #define DEBUGON        3
  75. #define DEBUGFULL        4
  76. #define DEBUGSYM        6
  77.  
  78. #ifndef    DEBUGLEVEL
  79. #define    DEBUGLEVEL    DEBUGOFF
  80. #endif    DEBUGLEVEL
  81.  
  82. /*
  83.     resumeLabel is used to control the insertion of labels for use with
  84.     the resume macro. If you do not use the resume macro and you wish
  85.     to have multible exceptions per label then you can add the
  86.     following define to you source code.
  87.  
  88.     #define resumeLabel(exception)    resume_ ## exception:    
  89. */
  90.  
  91. #define resumeLabel(exception)
  92.  
  93.  
  94. /*
  95.     trace and notrace are used for the traceOption for dprintf. If
  96.     trace is used then the actual behavior can be controled from
  97.     Macsbug. The macros in Macsbug are traceGo and traceBreak. traceGo
  98.     is the default and execution will continue after the break. If
  99.     traceBreak is used then execution will halt.
  100. */
  101.  
  102. #define    trace        "\p;dprintf;doTrace"
  103. #define    notrace    "\p;dprintf"
  104.  
  105. /*
  106.     traceon and debugon are used to test for options
  107. */
  108.  
  109. #define    traceon    ((DEBUGLEVEL > DEBUGWARN) && defined(TRACEON))
  110. #define    debugon    (DEBUGLEVEL > DEBUGWARN)
  111.  
  112. /*
  113.     Add some macros for DEBUGMIN and DEBUGSYM to keep the size down.
  114. */
  115.  
  116. #define    __DEBUGSMALL    ((DEBUGLEVEL == DEBUGMIN) ||            \
  117.                                  (DEBUGLEVEL == DEBUGSYM))
  118.  
  119. #if    DEBUGLEVEL == DEBUGMIN
  120. #define    __DebuggerBreak    Debugger()
  121. #elif    DEBUGLEVEL == DEBUGSYM
  122. #define  __DebuggerBreak    SysBreak()
  123. #endif
  124.  
  125. /*<FF>*/
  126. /*********************************************************************
  127.  
  128. ROUTINE
  129.     void dprintf(traceOption, format, ...)
  130.  
  131. DESCRIPTION
  132.     dprintf is used like printf only the information is displayed in
  133.     MacsBug. traceOption is used to specify whether the execution
  134.     should continue after the break or not. format contains
  135.     two types of objects: ordinary characters, which are displayed in
  136.     Macsbug, and coversion specifications, each of which causes
  137.     conversion and printing of the next successive argument to dprintf.
  138.     Each conversion specification begins with a % and ends with a
  139.     conversion character. Between % and the conversion character there
  140.     may be, in order:
  141.     
  142.     •    Zero or more flag characters, which modify the meaning of the
  143.         conversion specification.
  144.     •    A number that specifies the minimum field width. The converted
  145.         argument will be printed in a field at least this wide. If
  146.         necessary it will be padded on the left (or right, if left
  147.         adjustment is called for) to make up the field width.
  148.     •    A period, which separates the field width from the precision.
  149.     •    A number, the precision, that specifies the maximum number of
  150.         characters to be printed from a string, or the number of digits
  151.         after the decimal point of a floatingpoint value, or the minimum
  152.         number of digits for an integer.
  153.     •    An h if the integer is to be printed as a short, or l if as
  154.         long (ignored since int is long), or L to specify that the
  155.         following e, E, f, g, or G conversion is a long double.
  156.     
  157.     Note: A field width or precision may be indicated by an * instead
  158.     of a digit string. In this case, an integer arg parameter supplies
  159.     the field width or precision. The arg parameter that is actually
  160.     converted is not fetched until the conversion letter is seen;
  161.     therefore, the arg paramters specifying field width or precision
  162.     must appear immediately before the arg parameter (if any) to be
  163.     converted.
  164.     
  165.     The flag characters are:
  166.     
  167.         -        The result of the conversion will be left justified
  168.                 within the field.
  169.         +        The result of a signed conversion always begins with a
  170.                 sign (+ or -).
  171.         space    If the first character of a signed conversion is not a
  172.                 sign, a space will be prefixed to the result. This implies
  173.                 that if the space and + flags both appear, the space flag
  174.                 will be ignored.
  175.         #        The value is to be converted to an alternate form. For c,
  176.                 d, s, and u conversions, the flag has no effect. For o
  177.                 conversions, it increases the precision to force the first
  178.                 digit of the result to be zero. For x, and X conversions,
  179.                 a nonzero result will have 0x or 0X prefixed to it. For
  180.                 e, E, f, g, and G conversions, the result will always
  181.                 contain a decimal point, even if no digits follow the
  182.                 point. For g and G conversion, trailing zeros in the
  183.                 fractional part will not be removed from the result.
  184.         0        The 0 flag pads the field with zeros on the left only;
  185.                 this applies to d, i, o, u, x, X, e, E, f, g, and G
  186.                 conversions. The leading zeros pad the field width, and
  187.                 no space padding is performed. If both the 0 and - flags
  188.                 appear, the 0 flag is ignored. If a precision is specified
  189.                 for d, i, o, u, x, and X conversions, the 0 flag is
  190.                 ignored.
  191.     
  192.     The standard conversions are:
  193.     
  194.         d,i    int            Decimal number.
  195.         o        int            Unsigned octal number (w/o a leading zero).
  196.         x,X    int            Unsigned hexadecimal number (w/o a leading 0x
  197.                                 or oX), using abcdef or ABCDEF for 10,…,15.
  198.         u        int            Unsigned decimal number.
  199.         c        int            Single character.
  200.         s        char*            C string.
  201.         f        double        [-]m.dddddd, where the number of d's is given
  202.                                 by the precision (default 6).
  203.         e,E    double        [-]m.dddddde±xx or [-]m.ddddddE±xx, where the
  204.                                 number of d's is given by the precision
  205.                                 (default 6).
  206.         g,G    double        Use %e or %E if the exponent is less than -4
  207.                                 or greater than or equal to the precision;
  208.                                 otherwise use %f. Trailing zeros and a
  209.                                 trailing decimal point are not printed.
  210.         p        void*            Pointer.
  211.         %                        No argument is converted; print a %.
  212.     
  213.     The supported MPW extensions are:
  214.     
  215.         P        StringPtr    Pascal string.
  216.     
  217.     Of the MPW printf convertion characters only "n" is not supported.
  218.     In addition to the standard characters, the following are defined:
  219.     
  220.         b        Boolean        Outputs either true or false.
  221.         j        Point            Used like the d option.
  222.         J        point*        Fixed point. Used like the f option.
  223.         F        Fixed            Used like the f option.
  224.         T        Fract            Used like the f option.
  225.         r        Rect*            Displays the rect with each piece seperated by
  226.                                 ", ". Used like the d option.
  227.         R        rectangle*    Similar to r but for fixed point rectangles.
  228.                                 Used like the f option.
  229.         M        mapping.        Displays the mapping seperated by ", " and
  230.                                 "\n". The third column is displayed as fract.
  231.                                 Used like the f option.
  232.     
  233.         
  234.     dprintf requires that the MacsBug dcmd dprintf is present.
  235.     
  236.     Characters used:     bcdefghij l nop rs u  x
  237.                                 EFG  J LM  P R T   X
  238.     Not used:            a         k m   q  t vw yz
  239.                             ABCD   HI K  NO Q S UVW YZ
  240.     
  241.     See the MPW C Reference for more information on printf.
  242.  
  243. Echo "                                                            ∂n∂
  244.     PRINT            OFF,NOHDR                                    ∂n∂
  245.     INCLUDE        'Traps.a'                                    ∂n∂
  246.     PRINT            ON                                                ∂n∂
  247.     PROC                                                            ∂n∂
  248.     _DebugStr                                                    ∂n∂
  249.     SUBQ            #4,SP        ; Fix the stack                ∂n∂
  250.     ENDPROC                                                        ∂n∂
  251.     END                                                            ∂n∂
  252. " | Asm -l
  253.  
  254. *********************************************************************/
  255.  
  256. void dprintf(StringPtr, char[], ...)
  257.     = { 0xABFF, 0x594F };
  258.  
  259. /*<FF>*/
  260. /*********************************************************************
  261.  
  262. ROUTINE
  263.     void* check_dprintf(assertion, traceOption, format, ...)
  264.  
  265. DESCRIPTION
  266.     If assertion is non-zero then assertion is returned. Otherwise the
  267.     dprintf is invoked and zero is returned.
  268.     
  269. Echo "                                                            ∂n∂
  270.     PRINT            OFF,NOHDR                                    ∂n∂
  271.     INCLUDE        'Traps.a'                                    ∂n∂
  272.     PRINT            ON                                                ∂n∂
  273.     PROC                                                            ∂n∂
  274.     MOVE.L        (SP)+,D0    ; Pop value into D0            ∂n∂
  275.     BNE.S            @1            ; If !0 then branch            ∂n∂
  276.     _DebugStr                                                    ∂n∂
  277.     SUBQ            #4,SP        ; Fix the stack                ∂n∂
  278.     CLR.W            D0            ; Result is zero                ∂n∂
  279. @1    SUBQ            #4,SP        ; Fix stack for pop            ∂n∂
  280.     ENDPROC                                                        ∂n∂
  281.     END                                                            ∂n∂
  282. " | Asm -l
  283.     
  284. *********************************************************************/
  285.     
  286. void* check_dprintf(void*, StringPtr, char[], ...) =
  287.     { 0x201F, 0x6606, 0xABFF, 0x594F, 0x4240, 0x594F };
  288.     
  289. /*<FF>*/
  290. /*********************************************************************
  291.  
  292. ROUTINE
  293.     void* checkpos_dprintf(assertion, traceOption, format, ...)
  294.  
  295. DESCRIPTION
  296.     If assertion is positive then assertion is returned. Otherwise the
  297.     dprintf is invoked and zero is returned.
  298.     
  299. Echo "                                                            ∂n∂
  300.     PRINT            OFF,NOHDR                                    ∂n∂
  301.     INCLUDE        'Traps.a'                                    ∂n∂
  302.     PRINT            ON                                                ∂n∂
  303.     PROC                                                            ∂n∂
  304.     MOVE.L        (SP)+,D0    ; Pop value into D0            ∂n∂
  305.     BGE.S            @1            ; If >= 0 then branch        ∂n∂
  306.     _DebugStr                                                    ∂n∂
  307.     SUBQ            #4,SP        ; Fix the stack                ∂n∂
  308.     CLR.W            D0            ; Result is zero                ∂n∂
  309. @1    SUBQ            #4,SP        ; Fix stack for pop            ∂n∂
  310.     ENDPROC                                                        ∂n∂
  311.     END                                                            ∂n∂
  312. " | Asm -l
  313.     
  314. *********************************************************************/
  315.     
  316. void* checkpos_dprintf(void*, StringPtr, char[], ...) =
  317.     { 0x201F, 0x6C06, 0xABFF, 0x594F, 0x4240, 0x594F };
  318.  
  319. /*<FF>*/
  320. /*********************************************************************
  321.  
  322. MACRO
  323.     check(assertion)
  324.  
  325. DESCRIPTION
  326.     If debugging is on then check will test assertion and if it fails
  327.     break into the debugger. Otherwise check does nothing.
  328.  
  329. *********************************************************************/
  330.  
  331. #if    __DEBUGSMALL
  332.  
  333. #define check(assertion)                                                            \
  334.     do {                                                                                    \
  335.         if (assertion) ;                                                                \
  336.         else __DebuggerBreak;                                                        \
  337.     } while (false)
  338.  
  339. #elif    DEBUGLEVEL == DEBUGON
  340.  
  341. #define check(assertion)                                                            \
  342.     do {                                                                                    \
  343.         if (assertion) ;                                                                \
  344.         else {                                                                            \
  345.             dprintf(notrace, "Assertion \"%s\" Failed",    #assertion);    \
  346.         }                                                                                    \
  347.     } while (false)
  348.  
  349. #elif    DEBUGLEVEL == DEBUGFULL
  350.  
  351. #define check(assertion)                                                            \
  352.     do {                                                                                    \
  353.         if (assertion) ;                                                                \
  354.         else {                                                                            \
  355.             dprintf(notrace,    "Assertion \"%s\" Failed\n"                    \
  356.                                     "File: %s\n"                                        \
  357.                                     "Line: %d",                                            \
  358.                 #assertion, __FILE__, __LINE__);                                    \
  359.         }                                                                                    \
  360.     } while (false)
  361.     
  362. #else
  363.  
  364. #define check(assertion)
  365.  
  366. #endif
  367.  
  368. /*<FF>*/
  369. /*********************************************************************
  370.  
  371. MACRO
  372.     ncheck(assertion)
  373.  
  374. DESCRIPTION
  375.     If debugging is on then ncheck will test !assertion and if it fails
  376.     break into the debugger. Otherwise ncheck does nothing.
  377.  
  378. *********************************************************************/
  379.  
  380. #if    __DEBUGSMALL
  381.  
  382. #define ncheck(assertion)                                                            \
  383.     do {                                                                                    \
  384.         if (assertion) __DebuggerBreak;                                            \
  385.     } while (false)
  386.  
  387. #elif    DEBUGLEVEL == DEBUGON
  388.  
  389. #define ncheck(assertion)                                                            \
  390.     do {                                                                                    \
  391.         void*    __privateAssertion    = (void*)(assertion);                    \
  392.                                                                                             \
  393.         if (__privateAssertion) {                                                    \
  394.             dprintf(notrace, "Assertion \"!(%s [= %#08X])\" Failed",        \
  395.                 #assertion, __privateAssertion);                                    \
  396.         }                                                                                    \
  397.     } while (false)
  398.  
  399. #elif    DEBUGLEVEL == DEBUGFULL
  400.  
  401. #define ncheck(assertion)                                                            \
  402.     do {                                                                                    \
  403.         void*    __privateAssertion    = (void*)(assertion);                    \
  404.                                                                                             \
  405.         if (__privateAssertion) {                                                    \
  406.             dprintf(notrace,    "Assertion \"!(%s [= %#08X])\" Failed\n"    \
  407.                                     "File: %s\n"                                        \
  408.                                     "Line: %d",                                            \
  409.             #assertion, __privateAssertion, __FILE__, __LINE__);            \
  410.         }                                                                                    \
  411.     } while (false)
  412.  
  413. #else
  414.  
  415. #define ncheck(assertion)
  416.  
  417. #endif
  418.  
  419. /*<FF>*/
  420. /*********************************************************************
  421.  
  422. MACRO
  423.     check_action(assertion, action)
  424.  
  425. DESCRIPTION
  426.     If debugging is on then check_action will test assertion and if it
  427.     fails break into the debugger then execute action. Otherwise
  428.     check_action does nothing.
  429.     
  430. *********************************************************************/
  431.  
  432. #if    __DEBUGSMALL
  433.  
  434. #define check_action(assertion, action)                                        \
  435.     do {                                                                                    \
  436.         if (assertion) ;                                                                \
  437.         else {                                                                            \
  438.             __DebuggerBreak;                                                            \
  439.             { action }                                                                    \
  440.     } while (false)
  441.  
  442. #elif    DEBUGLEVEL == DEBUGON
  443.  
  444. #define check_action(assertion, action)                                        \
  445.     do {                                                                                    \
  446.         if (assertion) ;                                                                \
  447.         else {                                                                            \
  448.             dprintf(notrace, "Assertion \"%s\" Failed",    #assertion);    \
  449.             { action }                                                                    \
  450.         }                                                                                    \
  451.     } while (false)
  452.  
  453. #elif    DEBUGLEVEL == DEBUGFULL
  454.  
  455. #define check_action(assertion, action)                                        \
  456.     do {                                                                                    \
  457.         if (assertion) ;                                                                \
  458.         else {                                                                            \
  459.             dprintf(notrace,    "Assertion \"%s\" Failed\n"                    \
  460.                                     "File: %s\n"                                        \
  461.                                     "Line: %d",                                            \
  462.                 #assertion, __FILE__, __LINE__);                                    \
  463.             { action }                                                                    \
  464.         }                                                                                    \
  465.     } while (false)
  466.  
  467. #else
  468.  
  469. #define check_action(assertion, action)
  470.  
  471. #endif
  472.  
  473. /*<FF>*/
  474. /**************************************************************************************
  475.  
  476. MACRO
  477.     ncheck_action(assertion, action)
  478.  
  479. DESCRIPTION
  480.     If debugging is on then ncheck_action will test !assertion and if
  481.     it fails break into the debugger then execute action. Otherwise
  482.     ncheck_action does nothing.
  483.  
  484. *********************************************************************/
  485.  
  486. #if    __DEBUGSMALL
  487.  
  488. #define ncheck_action(assertion, action)                                        \
  489.     do {                                                                                    \
  490.         if (assertion) {                                                                \
  491.             __DebuggerBreak;                                                            \
  492.             { action }                                                                    \
  493.         }                                                                                    \
  494.     } while (false)
  495.  
  496. #elif    DEBUGLEVEL == DEBUGON
  497.  
  498. #define ncheck_action(assertion, action)                                        \
  499.     do {                                                                                    \
  500.         void*    __privateAssertion    = (void*)(assertion);                    \
  501.                                                                                             \
  502.         if (__privateAssertion) {                                                    \
  503.             dprintf(notrace, "Assertion \"!(%s [= %#08X])\" Failed",        \
  504.                 #assertion, __privateAssertion);                                    \
  505.             { action }                                                                    \
  506.         }                                                                                    \
  507.     } while (false)
  508.  
  509. #elif DEBUGLEVEL == DEBUGFULL
  510.  
  511. #define ncheck_action(assertion, action)                                        \
  512.     do {                                                                                    \
  513.         void*    __privateAssertion    = (void*)(assertion);                    \
  514.                                                                                             \
  515.         if (__privateAssertion) {                                                    \
  516.             dprintf(notrace,    "Assertion \"!(%s [= %#08X])\" Failed\n"    \
  517.                                     "File: %s\n"                                        \
  518.                                     "Line: %d",                                            \
  519.             #assertion, __privateAssertion, __FILE__, __LINE__);            \
  520.             { action }                                                                    \
  521.         }                                                                                    \
  522.     } while (false)
  523.  
  524. #else
  525.  
  526. #define ncheck_action(assertion, action)
  527.  
  528. #endif
  529.  
  530. /*<FF>*/
  531. /*********************************************************************
  532.  
  533. MACRO
  534.     require(assertion, exception)
  535.  
  536. DESCRIPTION
  537.     require will test assertion and if it fails:
  538.         break into the debugger if debugging is on.
  539.         goto exception.
  540.  
  541. *********************************************************************/
  542.  
  543. #if    __DEBUGSMALL
  544.  
  545. #define require(assertion, exception)                                            \
  546.     do {                                                                                    \
  547.         if (assertion) ;                                                                \
  548.         else {                                                                            \
  549.             __DebuggerBreak;                                                            \
  550.             goto exception;                                                            \
  551.             resumeLabel(exception);                                                    \
  552.         }                                                                                    \
  553.     } while (false)
  554.  
  555. #elif    DEBUGLEVEL == DEBUGON
  556.  
  557. #define require(assertion, exception)                                            \
  558.     do {                                                                                    \
  559.         if (assertion) ;                                                                \
  560.         else {                                                                            \
  561.             dprintf(notrace,    "Assertion \"%s\" Failed\n"                    \
  562.                                     "Exception \"%s\" Raised",                        \
  563.             #assertion, #exception);                                                \
  564.             goto exception;                                                            \
  565.             resumeLabel(exception);                                                    \
  566.         }                                                                                    \
  567.     } while (false)
  568.  
  569. #elif DEBUGLEVEL == DEBUGFULL
  570.  
  571. #define require(assertion, exception)                                            \
  572.     do {                                                                                    \
  573.         if (assertion) ;                                                                \
  574.         else {                                                                            \
  575.             dprintf(notrace,    "Assertion \"%s\" Failed\n"                    \
  576.                                     "Exception \"%s\" Raised\n"                    \
  577.                                     "File: %s\n"                                        \
  578.                                     "Line: %d",                                            \
  579.                 #assertion, #exception, __FILE__, __LINE__);                    \
  580.             goto exception;                                                            \
  581.             resumeLabel(exception);                                                    \
  582.         }                                                                                    \
  583.     } while (false)
  584.  
  585. #else
  586.  
  587. #define require(assertion, exception)                                            \
  588.     do {                                                                                    \
  589.         if (assertion) ;                                                                \
  590.         else {                                                                            \
  591.             goto exception;                                                            \
  592.             resumeLabel(exception);                                                    \
  593.         }                                                                                    \
  594.     } while (false)
  595.  
  596. #endif
  597.  
  598. /*<FF>*/
  599. /*********************************************************************
  600.  
  601. MACRO
  602.     nrequire(assertion, exception)
  603.  
  604. DESCRIPTION
  605.     nrequire will test !assertion and if it fails:
  606.         break into the debugger if debugging is on.
  607.         goto exception.
  608.  
  609. *********************************************************************/
  610.  
  611. #if    __DEBUGSMALL
  612.  
  613. #define nrequire(assertion, exception)                                            \
  614.     do {                                                                                    \
  615.         if (assertion) {                                                                \
  616.             DebugStr();                                                                    \
  617.             goto exception;                                                            \
  618.             resumeLabel(exception);                                                    \
  619.         }                                                                                    \
  620.     } while (false)
  621.  
  622. #elif    DEBUGLEVEL == DEBUGON
  623.  
  624. #define nrequire(assertion, exception)                                            \
  625.     do {                                                                                    \
  626.         void*    __privateAssertion    = (void*)(assertion);                    \
  627.                                                                                             \
  628.         if (__privateAssertion) {                                                    \
  629.             dprintf(notrace,    "Assertion \"!(%s [= %#08X])\" Failed\n"    \
  630.                                     "Exception \"%s\" Raised",                        \
  631.                 #assertion, __privateAssertion, #exception);                    \
  632.             goto exception;                                                            \
  633.             resumeLabel(exception);                                                    \
  634.         }                                                                                    \
  635.     } while (false)
  636.  
  637. #elif DEBUGLEVEL == DEBUGFULL
  638.  
  639. #define nrequire(assertion, exception)                                            \
  640.     do {                                                                                    \
  641.         void*    __privateAssertion    = (void*)(assertion);                    \
  642.                                                                                             \
  643.         if (__privateAssertion) {                                                    \
  644.             dprintf(notrace,    "Assertion \"!(%s [= %#08X])\" Failed\n"    \
  645.                                     "Exception \"%s\" Raised\n"                    \
  646.                                     "File: %s\n"                                        \
  647.                                     "Line: %d",                                            \
  648.                 #assertion, __privateAssertion, #exception, __FILE__,        \
  649.                 __LINE__);                                                                \
  650.             goto exception;                                                            \
  651.             resumeLabel(exception);                                                    \
  652.         }                                                                                    \
  653.     } while (false)
  654.  
  655. #else
  656.  
  657. #define nrequire(assertion, exception)                                            \
  658.     do {                                                                                    \
  659.         if (assertion) {                                                                \
  660.             goto exception;                                                            \
  661.             resumeLabel(exception);                                                    \
  662.         }                                                                                    \
  663.     } while (false)
  664.  
  665. #endif
  666.  
  667. /*<FF>*/
  668. /*********************************************************************
  669.  
  670. MACRO
  671.     require_action(assertion, exception, action)
  672.  
  673. DESCRIPTION
  674.     require_action will test assertion and if it fails:
  675.         break into the debugger if debugging is on.
  676.         execute action.
  677.         goto exception.
  678.  
  679. *********************************************************************/
  680.  
  681. #if    __DEBUGSMALL
  682.  
  683. #define require_action(assertion, exception, action)                        \
  684.     do {                                                                                    \
  685.         if (assertion) ;                                                                \
  686.         else {                                                                            \
  687.             __DebuggerBreak;                                                            \
  688.             { action }                                                                    \
  689.             goto exception;                                                            \
  690.             resumeLabel(exception);                                                    \
  691.         }                                                                                    \
  692.     } while (false)
  693.  
  694. #elif    DEBUGLEVEL == DEBUGON
  695.  
  696. #define require_action(assertion, exception, action)                        \
  697.     do {                                                                                    \
  698.         if (assertion) ;                                                                \
  699.         else {                                                                            \
  700.             dprintf(notrace,    "Assertion \"%s\" Failed\n"                    \
  701.                                     "Exception \"%s\" Raised",                        \
  702.             #assertion, #exception);                                                \
  703.             { action }                                                                    \
  704.             goto exception;                                                            \
  705.             resumeLabel(exception);                                                    \
  706.         }                                                                                    \
  707.     } while (false)
  708.  
  709. #elif DEBUGLEVEL == DEBUGFULL
  710.  
  711. #define require_action(assertion, exception, action)                        \
  712.     do {                                                                                    \
  713.         if (assertion) ;                                                                \
  714.         else {                                                                            \
  715.             dprintf(notrace,    "Assertion \"%s\" Failed\n"                    \
  716.                                     "Exception \"%s\" Raised\n"                    \
  717.                                     "File: %s\n"                                        \
  718.                                     "Line: %d",                                            \
  719.                 #assertion, #exception, __FILE__, __LINE__);                    \
  720.             { action }                                                                    \
  721.             goto exception;                                                            \
  722.             resumeLabel(exception);                                                    \
  723.         }                                                                                    \
  724.     } while (false)
  725.  
  726. #else
  727.  
  728. #define require_action(assertion, exception, action)                        \
  729.     do {                                                                                    \
  730.         if (assertion) ;                                                                \
  731.         else {                                                                            \
  732.             { action }                                                                    \
  733.             goto exception;                                                            \
  734.             resumeLabel(exception);                                                    \
  735.         }                                                                                    \
  736.     } while (false)
  737.  
  738. #endif
  739.  
  740. /*<FF>*/
  741. /*********************************************************************
  742.  
  743. MACRO
  744.     nrequire_action(assertion, exception, action)
  745.  
  746. DESCRIPTION
  747.     nrequire_action will test !assertion and if it fails:
  748.         break into the debugger if debugging is on.
  749.         execute action.
  750.         goto exception.
  751.  
  752. *********************************************************************/
  753.  
  754. #if    __DEBUGSMALL
  755.  
  756. #define nrequire_action(assertion, exception, action)                        \
  757.     do {                                                                                    \
  758.         if (assertion) {                                                                \
  759.             __DebuggerBreak;                                                            \
  760.             { action }                                                                    \
  761.             goto exception;                                                            \
  762.             resumeLabel(exception);                                                    \
  763.         }                                                                                    \
  764.     } while (false)
  765.  
  766. #elif DEBUGLEVEL == DEBUGON
  767.  
  768. #define nrequire_action(assertion, exception, action)                        \
  769.     do {                                                                                    \
  770.         void*    __privateAssertion    = (void*)(assertion);                    \
  771.                                                                                             \
  772.         if (__privateAssertion) {                                                    \
  773.             dprintf(notrace,    "Assertion \"!(%s [= %#08X])\" Failed\n"    \
  774.                                     "Exception \"%s\" Raised",                        \
  775.                 #assertion, __privateAssertion, #exception);                    \
  776.             { action }                                                                    \
  777.             goto exception;                                                            \
  778.             resumeLabel(exception);                                                    \
  779.         }                                                                                    \
  780.     } while (false)
  781.  
  782. #elif DEBUGLEVEL == DEBUGFULL
  783.  
  784. #define nrequire_action(assertion, exception, action)                        \
  785.     do {                                                                                    \
  786.         void*    __privateAssertion    = (void*)(assertion);                    \
  787.                                                                                             \
  788.         if (__privateAssertion) {                                                    \
  789.             dprintf(notrace,    "Assertion \"!(%s [= %#08X])\" Failed\n"    \
  790.                                     "Exception \"%s\" Raised\n"                    \
  791.                                     "File: %s\n"                                        \
  792.                                     "Line: %d",                                            \
  793.                 #assertion, __privateAssertion, #exception, __FILE__,        \
  794.                 __LINE__);                                                                \
  795.             { action }                                                                    \
  796.             goto exception;                                                            \
  797.             resumeLabel(exception);                                                    \
  798.         }                                                                                    \
  799.     } while (false)
  800.  
  801. #else
  802.  
  803. #define nrequire_action(assertion, exception, action)                        \
  804.     do {                                                                                    \
  805.         if (assertion) {                                                                \
  806.             { action }                                                                    \
  807.             goto exception;                                                            \
  808.             resumeLabel(exception);                                                    \
  809.         }                                                                                    \
  810.     } while (false)
  811.  
  812. #endif
  813.     
  814. /*<FF>*/
  815. /*********************************************************************
  816.  
  817. MACRO
  818.     resume(exception)
  819.  
  820. DESCRIPTION
  821.     resume will resume execution after the n/require/_action statement
  822.     specified by exception. Resume lables must be on (the default) in
  823.     order to use resume. If an action form of require was used then the
  824.     action will not be re-executed.
  825.  
  826. *********************************************************************/
  827.  
  828.  
  829. #define resume(exception)                                                            \
  830.     do {                                                                                    \
  831.         goto resume_ ## exception;                                                    \
  832.     } while (false)
  833.  
  834.  
  835. /*<FF>*/
  836. /********************************************************************/
  837.  
  838. #endif